#include <jni.h>
#include "../player/av_player_core.h"
#include "media_common.h"
extern "C" {
#include <libavutil/rational.h>
#include <libavutil/pixdesc.h>
#include <libavutil/samplefmt.h>
}

#define LOG_TAG "AVMediaInfoJNI"

// Java 层 MediaInfo 类路径
#define MEDIA_INFO_CLASS "com/example/mediacore/player/MediaInfo"

// 像素格式转字符串
static const char* getPixelFormatString(AVPixelFormat pix_fmt) {
    const char* fmt_name = av_get_pix_fmt_name(pix_fmt);
    return fmt_name ? fmt_name : "";
}

// 采样格式转字符串
static const char* getSampleFormatString(AVSampleFormat sample_fmt) {
    const char* fmt_name = av_get_sample_fmt_name(sample_fmt);
    return fmt_name ? fmt_name : "";
}

// AVRational 转 float
static float rationalToFloat(AVRational rational) {
    return (rational.den == 0) ? 0.0f : (float)rational.num / rational.den;
}

// JNI 方法：获取 MediaInfo
extern "C" JNIEXPORT jobject JNICALL
Java_com_example_mediacore_player_NativePlayer_nativeGetMediaInfo(
        JNIEnv* env,
        jobject thiz,
        jlong native_handle) {
    if (native_handle == 0) {
        return nullptr;
    }

    AVPlayerCore* player_core = reinterpret_cast<AVPlayerCore*>(native_handle);
    if (!player_core) {
        return nullptr;
    }

    // 获取 C++ 层媒体信息
    const McMediaInfo* c_media = player_core->getMediaInfo();

    long start_pts_us = c_media->start_pts_us;
    long duration_us = c_media->duration_us;
    long bit_rate = c_media->bit_rate;

    bool has_audio = false;
    bool has_video = false;
    McMediaInfoAudio info_audio;
    McMediaInfoVideo info_video;
    for (auto info : c_media->detail) {
        if (info.first == McMediaStreamType::AUDIO) {
            has_audio = true;
            const McMediaInfoAudio *info_ptr = (McMediaInfoAudio *)info.second;
            info_audio.stream_idx = info_ptr->stream_idx;
            info_audio.sample_rate = info_ptr->sample_rate;
            info_audio.sample_fmt = info_ptr->sample_fmt;
            av_channel_layout_copy(&info_audio.ch_layout, &info_ptr->ch_layout);
            info_audio.time_base = info_ptr->time_base;
        }
        if (info.first == McMediaStreamType::VIDEO) {
            has_video = true;
            const McMediaInfoVideo *info_ptr = (McMediaInfoVideo *)info.second;
            info_video.stream_idx = info_ptr->stream_idx;
            info_video.width = info_ptr->width;
            info_video.height = info_ptr->height;
            info_video.pix_fmt = info_ptr->pix_fmt;
            info_video.frame_rate = info_ptr->frame_rate;
            info_video.time_base = info_ptr->time_base;
        }
    }

    // 查找 MediaInfo 类
    jclass media_cls = env->FindClass(MEDIA_INFO_CLASS);
    if (!media_cls) {
        env->ExceptionClear();
        return nullptr;
    }

    // 获取构造方法（使用正确签名）
    jmethodID ctor = env->GetMethodID(
            media_cls,
            "<init>",
            // 签名严格对应 Java 构造方法参数类型和顺序
            "(JJJZIIILjava/lang/String;ZIIILjava/lang/String;F)V"
    );
    if (!ctor) {
        env->DeleteLocalRef(media_cls);
        env->ExceptionClear();
        return nullptr;
    }

    // 转换字符串
    jstring j_sample_fmt = env->NewStringUTF(getSampleFormatString(info_audio.sample_fmt));
    jstring j_pixel_fmt = env->NewStringUTF(getPixelFormatString(info_video.pix_fmt));
    if (!j_sample_fmt || !j_pixel_fmt) {
        env->DeleteLocalRef(media_cls);
        env->DeleteLocalRef(j_sample_fmt);
        env->DeleteLocalRef(j_pixel_fmt);
        return nullptr;
    }

    // 创建 MediaInfo 对象（参数顺序与 Java 构造方法完全一致）
    jobject j_media = env->NewObject(
            media_cls,
            ctor,
            // 通用信息
            (jlong)c_media->start_pts_us,       // long startPtsUs
            (jlong)c_media->duration_us,        // long durationUs
            (jlong)c_media->bit_rate,           // long bitRate
            // 音频信息
            (jboolean)has_audio,                    // int hasAudio
            (jint)info_audio.stream_idx,            // int audioStreamIdx
            (jint)info_audio.sample_rate,           // int sampleRate
            (jint)info_audio.ch_layout.nb_channels, // int audioChannels
            j_sample_fmt,                           // String sampleFormat
            // 视频信息
            (jboolean)has_video,                    // int hasVideo
            (jint)info_video.stream_idx,            // int videoStreamIdx
            (jint)info_video.width,                 // int width
            (jint)info_video.height,                // int height
            j_pixel_fmt,                            // String pixelFormat
            (jfloat)info_video.frame_rate.num       // float frameRate
    );

    // 释放局部引用
    env->DeleteLocalRef(media_cls);
    env->DeleteLocalRef(j_sample_fmt);
    env->DeleteLocalRef(j_pixel_fmt);

    return j_media;
}